package kassiopeia.gui

import grails.plugin.jms.Subscriber;
import javax.jms.Message;
import javax.jms.ObjectMessage;
import kassiopeia.commons.io.Ping;
import kassiopeia.commons.util.JmsUtils;
import org.apache.log4j.Logger;

class AgentService {
    private static final Logger log = Logger.getLogger(AgentService.class)
    public static PING_TTL = 15000l
    static transactional = true
    static exposes = ["jms"]

    def cachedPings = [:]
    def timestamps = [:]

    @Subscriber(topic = 'BROADCAST_TOPIC')
    synchronized def incomingPing(Message message) {
        Ping ping = JmsUtils.convertObjectMessage(message, Ping.class)

        if(ping == null) {
            log.warn('Unknow message type -> ignoring incoming JMS message')
            return
        }

        def agentId = ping.getSourceId()

        if(!cachedPings.containsKey(agentId)) {
            log.info 'Welcome new agent with ID: ' + agentId
        }

        cachedPings[agentId] = ping
        timestamps[agentId] = new Date().getTime()
        return null
    }

    synchronized def applyPingTTL() {
        def toRemove = []
        def now = new Date().getTime()
        timestamps.each { agentId, timestamp ->
            if(timestamp  < (now - PING_TTL)) {
                toRemove.add(agentId)
            }
        }

        if(toRemove.size() > 0)
            log.info 'We have few dead agents here: ' + toRemove

        toRemove.each { agentId ->
            timestamps.remove(agentId)
            cachedPings.remove(agentId)
        }
    }

    synchronized def getPing(agentId) {
        return cachedPings[agentId]
    }

    synchronized def getAllPings() {
        return cachedPings.values()
    }
}
